package com.kit.personalkit.controller;

import com.kit.personalkit.common.JsonResponseBody;
import com.kit.personalkit.mapper.UserMapper;
import com.kit.personalkit.pojo.dto.UserLoginDTO;
import com.kit.personalkit.pojo.dto.UserRegDTO;
import com.kit.personalkit.pojo.dto.UserUpdateDTO;
import com.kit.personalkit.pojo.vo.UserVO;
import com.kit.personalkit.security.CustomUserDetails;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import com.kit.personalkit.pojo.entity.User;
import org.springframework.web.multipart.MultipartFile;
import com.kit.personalkit.common.ResponseStatus;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;


@Slf4j
@RestController
@RequestMapping("/users/")
public class UserController {

    @Autowired
    private UserMapper mapper;
    @Autowired
    private ServletContext servletContext;
    @Autowired
    private AuthenticationManager manager;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Value("${staticPath}")
    private String staticPath;

    @RequestMapping("register")
    JsonResponseBody register(@RequestBody UserRegDTO userRegDTO) {
        UserVO userVO = mapper.selectByUserName(userRegDTO.getUserName());
        if (userVO != null) {//用户名已存在
            return new JsonResponseBody(ResponseStatus.USER_ALREADY_EXISTS);
        }
        User user = new User();
        BeanUtils.copyProperties(userRegDTO, user);
        //加密密码
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setAvatarUrl("/defaultAvatar.jpg");//默认头像路径
        user.setStatus(1);//    默认状态正常
        user.setUserType(1);//  默认是普通用户
        mapper.insert(user);
        return new JsonResponseBody(ResponseStatus.REGISTER_SUCCESS);
    }


    //用户状态 1:正常 0:封禁
    //用户类型 1:用户 0:管理员
    @RequestMapping("login")
    JsonResponseBody login(@RequestBody UserLoginDTO userLoginDTO) {
        log.info("开始处理登录请求:{}", userLoginDTO);
        //通过认证管理器启动Security的认证流程  返回认证结果对象
        Authentication result = manager.authenticate(new UsernamePasswordAuthenticationToken(
                userLoginDTO.getUserName(), userLoginDTO.getPassword()));

        CustomUserDetails cud = (CustomUserDetails) result.getPrincipal();
        if (cud.getStatus() == 0) {
            //用户被封禁
            return new JsonResponseBody(ResponseStatus.HAS_BEEN_BANNED);
        }

        //将认证结果保存到Security上下文中   让Security框架记住登录状态
        SecurityContextHolder.getContext().setAuthentication(result);
        //代码执行到这里时代表登录成功!如果登录失败Security框架会抛出异常
        log.info("登录成功");
        return new JsonResponseBody(ResponseStatus.LOGIN_SUCCESS, cud);
    }

    @RequestMapping("isLogin")
    JsonResponseBody isLogin(@AuthenticationPrincipal CustomUserDetails cud) {
//        System.out.println("cud = " + cud);
        if (cud != null) {
            return new JsonResponseBody(ResponseStatus.SUCCESS);
        }
        return new JsonResponseBody(ResponseStatus.FAILED);
    }

    @RequestMapping("logout")
    public void logout() {
        //从Security框架中删除认证数据
        SecurityContextHolder.clearContext();
    }


    @GetMapping("{userId}")
    JsonResponseBody getUserInfo(@PathVariable int userId) {
        UserVO userVO = mapper.selectByUserId(userId);
        if (userVO == null) {
            return new JsonResponseBody(ResponseStatus.USER_DOES_NOT_EXISTS);
        }
        return new JsonResponseBody(ResponseStatus.SUCCESS, userVO);
    }

    @RequestMapping("/uploadAvatar")
    JsonResponseBody uploadAvatar(MultipartFile multipartFile, @AuthenticationPrincipal CustomUserDetails cud) {
//        multipartFile名与 <el-upload 中的 name="multipartFile"一致
        String fileName = multipartFile.getOriginalFilename();
        String suffix = null;
        if (fileName != null) {
            suffix = fileName.substring(fileName.lastIndexOf("."));
        }
        fileName = UUID.randomUUID() + suffix;
//        fileName = "avatar" + suffix;

        if (cud == null) return null;
        String avatarPath = staticPath + "/avatars/" + cud.getUserId();
        File f_avatarPath = new File(avatarPath);
        if (!f_avatarPath.exists()) {
            f_avatarPath.mkdirs();
        }
        String url = "/avatars/" + cud.getUserId() + "/" + fileName;
        try {
            multipartFile.transferTo(new File(staticPath + url));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        System.out.println("url = " + url);

        File directory = new File(avatarPath);
        if (!directory.exists() || !directory.isDirectory()) {
            log.debug("指定的路径不是一个有效的目录。");
            return null;
        }
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isFile()) {
                    if (!file.getName().equals(fileName)) {
                        file.delete();
                        log.debug("已删除头像文件:{file.getAbsolutePath()}");
                    }
                }
            }
        }
        User user = new User();
        user.setUserId(cud.getUserId());
        user.setAvatarUrl(url);
        mapper.updateUser(user);


        return new JsonResponseBody(ResponseStatus.SUCCESS, url);


    }


    @PutMapping("{userId}")
    JsonResponseBody updateUserInfo(@PathVariable int userId, @RequestBody UserUpdateDTO userUpdateDTO, @AuthenticationPrincipal CustomUserDetails cud) {
        if (cud == null) return new JsonResponseBody(ResponseStatus.FAILED);
        User user = new User();
        BeanUtils.copyProperties(userUpdateDTO, user);
        user.setUserId(userId);
        user.setPassword(passwordEncoder.encode(user.getPassword()));


        int result = mapper.updateUser(user);
        if (result >= 1) {
            return new JsonResponseBody(ResponseStatus.UPDATE_SUCCESS);
        } else {
            return new JsonResponseBody(ResponseStatus.FAILED);
        }


    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("selectAllUser")
    JsonResponseBody selectAllUser(@RequestParam(defaultValue = "1") int pageNum,
                                   @RequestParam(defaultValue = "10") int pageSize){
        int offest = (pageNum - 1) * pageSize;
        List<User> userList = mapper.selectByPage(offest,pageSize);
        return new JsonResponseBody(ResponseStatus.SUCCESS,userList);
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("getTotalUsers")
    JsonResponseBody getTotalUsers(){
        int totalUsers = mapper.getTotalUsers();
        return new JsonResponseBody(ResponseStatus.SUCCESS,totalUsers);
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("updateUserStatus/{userId}/{status}")
    JsonResponseBody updateUserStatus(@PathVariable int userId, @PathVariable int status){
        System.out.println("userId = " + userId);
        System.out.println("status = " + status);
        User user = new User();
        user.setUserId(userId);
        user.setStatus(status);
        int result = mapper.updateUser(user);
        if (result > 0){
            return new JsonResponseBody(ResponseStatus.SUCCESS);
        }else
            return new JsonResponseBody(ResponseStatus.FAILED);
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("updateUserType/{userId}/{userType}")
    JsonResponseBody updateUserType(@PathVariable int userId, @PathVariable int userType){
        User user = new User();
        user.setUserId(userId);
        user.setUserType(userType);
        int result = mapper.updateUser(user);
        if (result > 0){
            return new JsonResponseBody(ResponseStatus.SUCCESS);
        }else
            return new JsonResponseBody(ResponseStatus.FAILED);
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("deleteUser/{userId}")
    JsonResponseBody deleteUser(@PathVariable int userId){
        int result = mapper.deleteUser(userId);
        if (result > 0){
            return new JsonResponseBody(ResponseStatus.SUCCESS);
        }else
            return new JsonResponseBody(ResponseStatus.FAILED);
    }

    @PreAuthorize("hasAuthority('ADMIN')")
    @RequestMapping("searchUsers/{keyword}")
    JsonResponseBody searchUsers(@PathVariable String keyword){
        List<User> userList = mapper.searchUsers(keyword);
        return new JsonResponseBody(ResponseStatus.SUCCESS,userList);
    }







}
